package net.grandnature.android.morse.encoder.example;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import net.grandnature.android.morse.encode.MorseEncoder;
import net.grandnature.android.morse.player.MixRunner;
import net.grandnature.android.morse.player.MorseFlushPlayer;
import net.grandnature.android.morse.player.MorseGorillaPlayer;
import net.grandnature.android.morse.player.MorseGorillaPoolPlayer;
import net.grandnature.android.morse.player.MorseSoundPlayer;
import net.grandnature.android.morse.player.MorseStringBuilder;
import net.grandnature.android.morse.player.MorseVibratePlayer;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class Main extends Activity implements View.OnClickListener {
    /** Called when the activity is first created. */
    EditText text;
    Button buttonFlush;
    Button buttonVib;
    Button buttonPlaySound;
    Button buttonGori;
    Button buttonMix;
    View layout;
    Handler handler;
    private static final int TIME_STEP = 100;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        text = (EditText)findViewById(R.id.text);
        layout = findViewById(R.id.layout);
        handler = new Handler();
        buttonFlush = (Button)findViewById(R.id.button_flush);
        buttonPlaySound = (Button)findViewById(R.id.button_sound);
        buttonVib = (Button)findViewById(R.id.button_vib);
        buttonFlush.setOnClickListener(this);
        buttonPlaySound.setOnClickListener(this);
        buttonVib.setOnClickListener(this);
        buttonGori= (Button)findViewById(R.id.button_gori);
        buttonGori.setOnClickListener(this);
        buttonGori= (Button)findViewById(R.id.button_gori2);
        buttonGori.setOnClickListener(this);
        buttonMix= (Button)findViewById(R.id.button_mix);
        buttonMix.setOnClickListener(this);
        Intent intent = getIntent();
        if(intent!=null) {
        	if(Intent.ACTION_SEND.equals(intent.getAction())) {
        		if("gorilla".equals(intent.getScheme())) {
        			String msg = intent.getStringExtra("gori_message");
        			int type = intent.getIntExtra("gori_type", 0);
        			text.setText(msg);
        			if(type>0) {
            			onClick(buttonGori);
        			} else {
            			onClick(buttonMix);
        			}
        			
        		}
        	}
        }
    }
    @Override
	protected void onDestroy() {
		super.onDestroy();
		System.exit(0);
	}


    @Override
	public void onClick(View v) {
		new ExecuteTask(Main.this, v.getId()).execute(text.getText().toString());
		
	}
	
    private void doPlaySound(String org) {
		DataOutputStream out = null;
		try {
			out =  new DataOutputStream(new FileOutputStream(new File(Environment.getExternalStorageDirectory(), "12345")));
	        MorseEncoder enc = new MorseEncoder();
	        String encoded = enc.encode(org);
	        Log.v("LOG","org:" + org + ", dst:" + encoded);
	        MorseSoundPlayer sp = new MorseSoundPlayer(600,TIME_STEP);
	        sp.setDataOutputStream(out);
	        MorseStringBuilder msp1 = new MorseStringBuilder();
	        msp1.addPlayer(sp);
	        msp1.morsePlay(encoded);
	        msp1.close();
		} catch (Throwable t) {
			t.printStackTrace();
		} finally {
			if(out!=null) {
				try {
					out.flush();
					out.close();
				} catch (IOException e) {
				}
//				SoundDataUtils.addWavHeader(tempFile, file, frequency);
			}
		}
    }

    private void doFlush(String org) {
	        MorseEncoder enc = new MorseEncoder();
	        String encoded = enc.encode(org);
	        Log.v("LOG","org:" + org + ", dst:" + encoded);
	        MorseFlushPlayer fp = new MorseFlushPlayer(handler, layout, TIME_STEP);
	        MorseStringBuilder msp1 = new MorseStringBuilder();
	        msp1.addPlayer(fp);
	        msp1.morsePlay(encoded);
	        msp1.close();
    }
    private void doVib(String org) {
        MorseEncoder enc = new MorseEncoder();
        String encoded = enc.encode(org);
        Log.v("LOG","org:" + org + ", dst:" + encoded);
        MorseVibratePlayer vp = new MorseVibratePlayer(TIME_STEP);
        vp.setContext(this);
        MorseStringBuilder msp1 = new MorseStringBuilder();
        msp1.addPlayer(vp);
        msp1.morsePlay(encoded);
        msp1.close();
    }
    
    private void doGori(String org) {
		DataOutputStream out = null;
		try {
			out =  new DataOutputStream(new FileOutputStream(new File(Environment.getExternalStorageDirectory(), "12345")));
	        MorseEncoder enc = new MorseEncoder();
	        String encoded = enc.encode(org);
	        Log.v("LOG","org:" + org + ", dst:" + encoded);
	        MorseGorillaPlayer gp = new MorseGorillaPlayer(600,TIME_STEP, this, R.raw.u, R.raw.ho);
	        gp.setDataOutputStream(out);
	        MorseStringBuilder msp1 = new MorseStringBuilder();
	        msp1.addPlayer(gp);
	        msp1.morsePlay(encoded);
	        msp1.close();
		} catch (Throwable t) {
			t.printStackTrace();
		} finally {
			if(out!=null) {
				try {
					out.flush();
					out.close();
				} catch (IOException e) {
				}
//				SoundDataUtils.addWavHeader(tempFile, file, frequency);
			}
		}
    }

    private void doGoriPool(String org) {
		DataOutputStream out = null;
		try {
			out =  new DataOutputStream(new FileOutputStream(new File(Environment.getExternalStorageDirectory(), "12345")));
	        MorseEncoder enc = new MorseEncoder();
	        String encoded = enc.encode(org);
	        Log.v("LOG","org:" + org + ", dst:" + encoded);
	        MorseGorillaPoolPlayer gp = new MorseGorillaPoolPlayer(600,TIME_STEP, this, R.raw.u, R.raw.ho);
	        MorseStringBuilder msp1 = new MorseStringBuilder();
	        msp1.addPlayer(gp);
	        msp1.morsePlay(encoded);
	        msp1.close();
		} catch (Throwable t) {
			t.printStackTrace();
		} finally {
			if(out!=null) {
				try {
					out.flush();
					out.close();
				} catch (IOException e) {
				}
//				SoundDataUtils.addWavHeader(tempFile, file, frequency);
			}
		}
    }
    
    private void doMix(String org) {
    	ExecutorService ex =  Executors.newFixedThreadPool(4);

        MorseEncoder enc = new MorseEncoder();
        String encoded = enc.encode(org);
        Log.v("LOG","org:" + org + ", dst:" + encoded);
        
        //prepare sound
        DataOutputStream out = null;
		try {
			out =  new DataOutputStream(new FileOutputStream(new File(Environment.getExternalStorageDirectory(), "12345")));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
        Log.v("LOG","org:" + org + ", dst:" + encoded);
        
        //sound
        MorseSoundPlayer sp = new MorseSoundPlayer(600,100);
        sp.setDataOutputStream(out);

        
        //vibe
        MorseVibratePlayer vp = new MorseVibratePlayer(TIME_STEP);
        vp.setContext(this);

        //flush
        Log.v("LOG","org:" + org + ", dst:" + encoded);
        MorseFlushPlayer fp = new MorseFlushPlayer(handler, layout, 100);
        
        //gori
        MorseGorillaPlayer gp = new MorseGorillaPlayer(600,TIME_STEP, this, R.raw.u, R.raw.ho);
        sp.setDataOutputStream(out);
        
        
        //execute
//        ex.execute(new MixRunner(encoded, sp));
//        ex.execute(new MixRunner(encoded, vp));
        ex.execute(new MixRunner(encoded, fp));
        ex.execute(new MixRunner(encoded, gp));
        
        
		ex.shutdown();

        
    }
    
    
	private class ExecuteTask extends AsyncTask<String, Integer, Exception> {
		private final Context context;
		private final int rid;

		public ExecuteTask(Context context, int rid) {
			this.context = context;
			this.rid = rid;
		}
		@Override
		protected Exception doInBackground(String... params) {
			switch (rid) {
			case R.id.button_flush:
				doFlush(params[0]);
				break;
			case R.id.button_sound:
				doPlaySound(params[0]);
				break;
			case R.id.button_vib:
				doVib(params[0]);
				break;
			case R.id.button_gori:
				doGori(params[0]);
//				doGoriPool(params[0]);
				break;
			case R.id.button_gori2:
//				doGori(params[0]);
				doGoriPool(params[0]);
				break;
			case R.id.button_mix:
				doMix(params[0]);
				break;
			default:
				break;
			}
			return null;
		}
	}
}